package ua.at.tsvetkov.samizdat.data;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import ua.at.tsvetkov.application.AppConfig;
import ua.at.tsvetkov.samizdat.Const;
import ua.at.tsvetkov.samizdat.R;
import ua.at.tsvetkov.samizdat.database.ContentProviderSamizdat;
import ua.at.tsvetkov.util.Log;
import android.app.Service;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;

public class AsyncTaskUpdate extends AsyncTask<Void, Integer, Void> {

	private Context				context;

	private ArrayList<String>	genresCollection;

	private int						currentProgress	= -1;

	public AsyncTaskUpdate(Service context) {
		this.context = context;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		genresCollection = new ArrayList<String>();

		Cursor cursor = context.getContentResolver().query(Uri.parse(ContentProviderSamizdat.GENRE_CONTENT_URI + "/"), null, null, null, null);
		cursor.moveToFirst();
		if (cursor.getCount() != 0) {
			do {
				genresCollection.add(cursor.getString(1));
			} while (cursor.moveToNext());
		}

	}

	@Override
	protected Void doInBackground(Void... params) {

		long lastTimeUpdate = AppConfig.getLong(Const.LAST_UPDATE_DATE, -1);

//		Date d1 = new Date("01/01/2007 12:00:00");
//		Date d2 = new Date("02/29/2007 12:00:00");

		Calendar start = Calendar.getInstance();
//		start.setTime(d1);
		 if (lastTimeUpdate != -1) {
		 start.setTimeInMillis(lastTimeUpdate);
		 }

		Calendar end = Calendar.getInstance();
//		end.setTime(d2);
		
		float daysBetween = (float) daysBetween(start, end) + 1;
		float currentDay = 1;
		try {
			BufferedReader in = null;
			InputStream is = null;
			InputStreamReader br = null;

			Date current = start.getTime();

			SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
			String currentDateInString = dateFormat.format(current);

			HttpURLConnection connection;
			URL url = new URL(Url.getBooksUrlUpdate() + currentDateInString);
			connection = (HttpURLConnection) url.openConnection();
			connection.setConnectTimeout(Const.TIMEOUT * 15 * 10);
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
			connection.setRequestProperty("User-Agent", "Android reader");

			is = connection.getInputStream();
			br = new InputStreamReader(is, Const.ENCODING);
			in = new BufferedReader(br, 12000);

			for (; !start.after(end); start.add(Calendar.DATE, 1)) {

				while (true) {
					ContentValues bookValues = new ContentValues();
					StringBuffer genresBuffer = new StringBuffer("");

					for (int i = 0; i < genresCollection.size(); i++) {
						genresBuffer.append("0");
					}

					String[] stsWR = split(in.readLine(), 10);

					if (stsWR == null) {
						break;
					}

					if (stsWR.length == 10) {
						bookValues.put(Const.OBJECT, stsWR[0]);
						bookValues.put(Const.AUTHOR, stsWR[1]);
						// bookValue.get().put(Const.TITLE, removeHtmlTag(removeSpaces(stsWR[2])));
						// bookValue.get().put(Const.TITLE, removeHtmlTag(stsWR[2]));
						// bookValue.get().put(Const.TITLE, removeSpaces(stsWR[2]));
						bookValues.put(Const.TITLE, stsWR[2]);
						bookValues.put(Const.TYPE, stsWR[3]);
						bookValues.put(Const.SIZE, stsWR[4]);
						try {
							if (stsWR[5].length() != 0) {
								SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
								Date date = format.parse(stsWR[5]);
								bookValues.put(Const.DATE, date.getTime());
							} else {
								bookValues.put(Const.DATE, 0);
							}
						} catch (ParseException ex) {
							bookValues.put(Const.DATE, 0);
						}

						try {
							if (stsWR[6].length() == 0) {
								bookValues.put(Const.BALL, 0);
							} else {
								bookValues.put(Const.BALL, Double.valueOf(stsWR[6]));
							}
						} catch (NumberFormatException ex) {
							bookValues.put(Const.BALL, 0);
						}
						bookValues.put(Const.COUNTER, stsWR[7]);
						bookValues.put(Const.ALL_JANR, stsWR[8]);
						bookValues.put(Const.ANNOT, stsWR[9]);

						for (String genre : stsWR[8].split(";")) {
							if (genresCollection.contains(genre)) {
								for (int i = 0; i < genresCollection.size(); i++) {
									if (genre.equals(genresCollection.get(i))) {
										genresBuffer.replace(i, i + 1, "1");
									}
								}
							}
						}
						bookValues.put(Const.BOOK_GENRES, genresBuffer.toString());
						genresBuffer = null;

						context.getContentResolver().insert(ContentProviderSamizdat.BOOK_CONTENT_URI, bookValues);
					}
				}

				publishProgress((int) (currentDay / daysBetween * 100));
				currentDay++;
			}
			connection.disconnect();
		} catch (Exception e) {
			Log.e(e);
		}
		Log.v(context.getString(R.string.UPDATING_SUCCESS));
		return null;
	}

	@Override
	protected void onProgressUpdate(Integer... progress) {
		if (progress[0] != currentProgress) {
			currentProgress = progress[0];
			Intent broadcastIntent = new Intent(Const.BROADCAST_MESSAGE).putExtra(Const.UPDATE_LOADING_PERCENTS, currentProgress);
			((Service) context).sendBroadcast(broadcastIntent);
		}
	}

	@Override
	protected void onPostExecute(Void result) {
		super.onPostExecute(result);
		((Service) context).stopSelf();
	}

	private static String[] split(String st, int count) {
		if (st != null) {
			String[] data = st.split("\\|");
			if (data.length == count) {
				return data;
			} else {
				String[] newData = new String[count];
				if (data.length < count)
					count = data.length;
				for (int i = 0; i < count; i++) {
					newData[i] = data[i];
				}
				for (int i = data.length; i < newData.length; i++) {
					newData[i] = "";
				}
				return newData;
			}
		} else {
			return null;
		}
	}

	//
	// private static ContentValues[] cutNullFromArray(ContentValues[] array) {
	// ArrayList<ContentValues> tmpList = new ArrayList<ContentValues>();
	// for (ContentValues currentContentValue : array) {
	// if (currentContentValue != null) {
	// tmpList.add(currentContentValue);
	// }
	// }
	// return tmpList.toArray(new ContentValues[tmpList.size()]);
	// }

	public static long daysBetween(Calendar startDate, Calendar endDate) {
		Calendar date = (Calendar) startDate.clone();
		long daysBetween = 0;
		while (date.before(endDate)) {
			date.add(Calendar.DAY_OF_MONTH, 1);
			daysBetween++;
		}
		return daysBetween;
	}

	public static String removeHtmlTag(String src) {
		if (src == null)
			return null;
		return src.replaceAll("&nbsp;", " ").replaceAll("<.*?>|Ђ|ђ|&shy;", "").replaceAll("&quot;", "\"");
	}

}
